//
// Created by ftd on 2021/8/18.
//

#include "net_msg/net_msg_manager.h"
#include <string.h>
#include <stdio.h>
#include "config/system_config.h"
#include "protocol/protocol.h"
#include "utils/rand_helper.h"
#include "demo.h"

NetMsgManager& NetMsgManager::Instance() {
    static NetMsgManager instance;
    return instance;
}

NetMsgManager::NetMsgManager() {
    srand((unsigned int)time(nullptr));
}

NetMsgManager::~NetMsgManager() {
    for (auto& th : net_threads_) {
        if (th.joinable())
            th.join();
    }
}

bool NetMsgManager::Run() {
    auto thread_cnt = std::thread::hardware_concurrency() / 2;
    if (0 == thread_cnt)
        thread_cnt = 1;
    net_threads_.resize(thread_cnt);
    for (unsigned int i = 0; i < thread_cnt; ++i) {
        net_threads_[i] = std::thread(&NetMsgManager::MakeNetMsg, this);
    }
    return true;
}

void NetMsgManager::MakeNetMsg() {
    uint8_t buffer[200] = {0};
    auto& demo = Demo::Instance();
    auto msg_head = (MsgHead*)buffer;
    auto config = SystemConfig::Instance().GetConfig();
    for (auto it = config->begin(); !demo.IsExit(); ++it) {
        if (it == config->end()) {
            it = config->begin();
        }
        msg_head->msg_id = it->first;
        switch (msg_head->msg_id) {
            case kOpenRoom:{
                auto msg = (OpenRoomOperate*)(msg_head+1);
                memset(msg, 0x00, sizeof(*msg));
                msg->room_id = Rand(10000);
                msg->join_score_lower_limit = Rand(1000000);
                msg->join_level_lower_limit = Rand(1000) ;
                msg->tables_cnt = Rand(100);
                snprintf(msg->open_info, sizeof(msg->open_info), it->second.operate_info);
                msg_head->msg_size = sizeof(*msg);
                break;
            }
            case kModifyRoom: {
                auto msg = (ModifyRoomOperate*)(msg_head+1);
                memset(msg, 0x00, sizeof(*msg));
                msg->room_id = Rand(10000);
                msg->join_score_lower_limit = Rand(1000000);
                msg->join_level_lower_limit = Rand(1000) ;
                snprintf(msg->modify_info, sizeof(msg->modify_info), it->second.operate_info);
                msg_head->msg_size = sizeof(*msg);
                break;
            }
            case kRestartRoom: {
                auto msg = (RestartRoomOperate*)(msg_head+1);
                memset(msg, 0x00, sizeof(*msg));
                msg->room_id = Rand(10000);
                snprintf(msg->restart_info, sizeof(msg->restart_info), it->second.operate_info);
                msg_head->msg_size = sizeof(*msg);
                break;
            }
            case kDeleteRoom: {
                auto msg = (DeleteRoomOperate*)(msg_head+1);
                memset(msg, 0x00, sizeof(*msg));
                msg->room_id = Rand(10000);
                snprintf(msg->delete_info, sizeof(msg->delete_info), it->second.operate_info);
                msg_head->msg_size = sizeof(*msg);
                break;
            }
            case kCloseRoom: {
                auto msg = (CloseRoomOperate*)(msg_head+1);
                memset(msg, 0x00, sizeof(*msg));
                msg->room_id = Rand(10000);
                snprintf(msg->close_info, sizeof(msg->close_info), it->second.operate_info);
                msg_head->msg_size = sizeof(*msg);
                break;
            }
            default:
                break;
        }
        demo.PutMsg(buffer, msg_head->msg_size+sizeof(MsgHead));
        if (!demo.IsStressTest())
            std::this_thread::sleep_for(std::chrono::milliseconds(rand()%100+10));
    }
}
